#include "analysis.h"

analysis::~analysis()
{
}

void analysis::setup_data()
{
    analysis::data_raw = new D_RAW[DATA_RAW_ROWS * (64) + (sizeof(float) * 6)];
}

int analysis::load_data()
{
    int row = 0;
    string s, c;
    ifstream tfile(TRAINING_FILE);

    if (tfile.good())
    {
        while (getline(tfile, s))
        {
            stringstream lstream(s);
            getline(lstream, c, ',');
            data_raw[row].dtime = c;
            getline(lstream, c, ',');
            data_raw[row].dopen = boost::lexical_cast<float>(c);
            getline(lstream, c, ',');
            data_raw[row].dhigh = boost::lexical_cast<float>(c);
            getline(lstream, c, ',');
            data_raw[row].dlow = boost::lexical_cast<float>(c);
            getline(lstream, c, ',');
            data_raw[row].dclose = boost::lexical_cast<float>(c);
            getline(lstream, c, ',');
            data_raw[row].dvol = boost::lexical_cast<float>(c);
            getline(lstream, c, ',');
            data_raw[row].dres = boost::lexical_cast<float>(c);
            row++;
        }
        analysis::num_data = row;
    }
    else
    {
        analysis::num_data = -1;
    }
    analysis::data_ma = new float[analysis::num_data];
    analysis::data_so_simple = new float[analysis::num_data];
    analysis::data_so_smooth = new float[analysis::num_data];

    return num_data;
}

void analysis::build_ma()
{
    float * dclose = analysis::get_dclose();
    float * s;

    for (int i = 0; i < analysis::num_data; i++)
    {
        if (i < MOVING_AVERAGE_PERIOD)
        {
            analysis::data_ma[i] = 0;
        }
        else
        {
            float s = 0;
            for (int j = 0; j < MOVING_AVERAGE_PERIOD; j++)
            {
                if (dclose[i] != NULL)
                {
                    s += dclose[i];
                }
            }
            float avg = s / MOVING_AVERAGE_PERIOD;
            analysis::data_ma[i] = analysis::data_ma[i - 1] - avg;
        }
    }
}

void analysis::build_so()
{
    float * dhigh = analysis::get_dhigh();
    float * dlow = analysis::get_dlow();
    float * dclose = analysis::get_dclose();

    for (int i = 0; i < analysis::num_data; i++)
    {
        analysis::data_so_simple[i] = 100 * ((dclose - dlow) / (dhigh - dlow));

        if (i < MOVING_AVERAGE_PERIOD)
        {
            analysis::data_so_smooth[i] = 0;
        }
        else
        {
            float s = 0;
            for (int j = 0; j < MOVING_AVERAGE_PERIOD; j++)
            {
                if (data_so_simple[i] != NULL)
                {
                    s += data_so_simple[i];
                }
            }
            float avg = s / MOVING_AVERAGE_PERIOD;
            analysis::data_so_smooth[i] = analysis::data_so_smooth[i - 1] - avg;
        }
    }
}

void analysis::build_rsi()
{
    float * dclose = analysis::get_dclose();
    float alpha = 2 / (MOVING_AVERAGE_PERIOD + 1);
    float u, d, u_ema, d_ema;

    analysis::data_ema[0] = 0;
    for (int i = 1; i < analysis::num_data; i++)
    {
        // calculate ema U
        u = dclose[i] - dclose[i - 1];
        if (i < MOVING_AVERAGE_PERIOD)
        {
            analysis::data_so_smooth[i] = 0;
        }
        else
        {
            float s = 0;
            for (int j = 0; j < MOVING_AVERAGE_PERIOD; j++)
            {
                if (data_so_simple[i] != NULL)
                {
                    s += data_so_simple[i];
                }
            }
            float avg = s / MOVING_AVERAGE_PERIOD;
            analysis::data_so_smooth[i] = analysis::data_so_smooth[i - 1] - avg;
        }

        // calculate ema D
        d = dclose[i - 1] - dclose[i];

        // calculate RS

        // calculate RSI
        analysis::data_ema[i] = analysis::data_ema[i - 1] + alpha * (dclose[i] - analysis::data_ema[i - 1]);
    }
}

void analysis::build_m()
{

}

void analysis::build_ema()
{
    float * dclose = analysis::get_dclose();
    float alpha = 2 / (MOVING_AVERAGE_PERIOD + 1);

    analysis::data_ema[0] = 0;
    for (int i = 1; i < analysis::num_data; i++)
    {
        analysis::data_ema[i] = analysis::data_ema[i - 1] + alpha * (dclose[i] - analysis::data_ema[i - 1]);
    }
}

void analysis::build_tea()
{

}

void analysis::build_fama()
{

}

void analysis::build_sd()
{

}

float * analysis::get_dopen()
{
    float * val = new float[analysis::num_data];

    for (int i = 0; i < analysis::num_data; i++)
    {
        val[i] = analysis::data_raw[i].dopen;
    }

    return val;
}

float * analysis::get_dhigh()
{
    float * val = new float[analysis::num_data];

    for (int i = 0; i < analysis::num_data; i++)
    {
        val[i] = analysis::data_raw[i].dhigh;
    }

    return val;
}

float * analysis::get_dlow()
{
    float * val = new float[analysis::num_data];

    for (int i = 0; i < analysis::num_data; i++)
    {
        val[i] = analysis::data_raw[i].dlow;
    }

    return val;
}

float * analysis::get_dclose()
{
    float * val = new float[analysis::num_data];

    for (int i = 0; i < analysis::num_data; i++)
    {
        val[i] = analysis::data_raw[i].dclose;
    }

    return val;
}
